package revisaosistematica;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;

/**
 *
 * @author claudiane
 */
public class HashToken {

	//Declarando a hasMap que ira armazenar o arquivo invertido
	//private HashMap<String, LinkedList<Registro>> hash = new HashMap<String, LinkedList<Registro>>();

	public HashMap<String, List<Registro>> hash = new HashMap<String, List<Registro>>();


	public HashMap<String, List<Registro>> getHash() {
		return hash;
	}

	public void setHash(HashMap<String, List<Registro>> hashToken) {
		hash = hashToken;
	}


	//Adiciona o token e o numero do documento na hash
	public int put(String token, int numDoc, int pmaxFreq, String titulo) {

		int maxFreq = pmaxFreq;

		//Verifica se o token a ser inserido não é vazio
		if (token.equals("")) return maxFreq;

		//verifica se o token já existe na hash
		if (hash.containsKey(token)){

			//obtem os valores para cada token(chave)
			List<Registro> list = hash.get(token);

			//variável de controle se inseriu na hash
			boolean inseriu = false;

			//percorre todas os registros(documento e valor) da chave
			for (Registro registro: list){

				//verifica se o numero do documento passado por parametro é igual a um valor ja existente na hash
				if (registro.getIndice() == numDoc){

					//incrementa o valor da frequencia do termo no documento
					registro.incValor();

					if (registro.getValor() > maxFreq){

						maxFreq = (int)registro.getValor();
					}

					inseriu = true;
					break;
				}
			}

			//se nao inseriu é porque é um documento novo
			if (!inseriu){

				//cria um novo registro com o numero do documento e frequencia = 1
				list.add(new Registro(numDoc,1,0,titulo));
			}

			hash.put(token, list);

		}else{

			//se o token ainda nao existe na hash, cria uma lista 
			List<Registro> list = new ArrayList<Registro>();

			//adiciona na lista o numero do documento e a frequencia = 1
			list.add(new Registro(numDoc,1,0,titulo));

			//adiciona na hash o token e a lista de registro(documento e frequencia)
			hash.put(token, list);

		}
		return maxFreq;
	}

	//Adiciona o token e o numero do documento na hash
	public int putAbs(String token, int numDoc, int pmaxFreqAbs, String titulo) {

		int maxFreqAbs = pmaxFreqAbs;

		token = token.trim();

		//Verifica se o token a ser inserido não é vazio
		if (token.equals("")) return maxFreqAbs;

		//verifica se o token já existe na hash
		if (hash.containsKey(token)){

			//obtem os valores para cada token(chave)
			List<Registro> list = hash.get(token);

			//variável de controle se inseriu na hash
			boolean inseriu = false;

			//percorre todas os registros(documento e valor) da chave
			for (Registro registro: list){

				//verifica se o numero do documento passado por parametro é igual a um valor ja existente na hash
				if (registro.getIndice() == numDoc){

					//incrementa o valor da frequencia do termo no documento
					registro.incValorAbs();

					if (registro.getValorAbs() > maxFreqAbs){

						maxFreqAbs = (int)registro.getValorAbs();
					}

					inseriu = true;
					break;
				}
			}

			//se nao inseriu é porque é um documento novo
			if (!inseriu){

				//cria um novo registro com o numero do documento e frequencia = 1
				list.add(new Registro(numDoc,0,1,titulo));
			}

			hash.put(token, list);

		}else{

			//se o token ainda nao existe na hash, cria uma lista 
			List<Registro> list = new ArrayList<Registro>();

			//adiciona na lista o numero do documento e a frequencia = 1
			list.add(new Registro(numDoc,0,1,titulo));

			//adiciona na hash o token e a lista de registro(documento e frequencia)
			hash.put(token, list);
		}
		return maxFreqAbs;
	}

	//atualiza a hash trocando a frequencia pelo valor do peso para cada token
	public void atualizaHash(float vetorNorma[]){

		//obtem o conjunto de chaves da hash
		Set<String> chaves = hash.keySet();

		//percorre todas as chaves da hash
		for (String chaveAtual: chaves){

			//obtem o conjunto de registro de cada chave
			List<Registro> lista = hash.get(chaveAtual);

			//percorre todas os registros da chave
			for (Registro registro: lista){               

				float valor = registro.getValor();
				float maxFreq = Extracao.getVetorMaxFreq().get(registro.getIndice());
				float freqNormalizada = valor/maxFreq;

				//Atualiza a frequencia para a frequencia normalizada
				registro.setValor(freqNormalizada);

				// Inicia o calculo da norma do documento fazendo o somatorio do quadrado do peso
				vetorNorma[registro.getIndice()] = vetorNorma[registro.getIndice()] + (freqNormalizada * freqNormalizada);
			}
		}

		// Atualiza vetor norma para raiz quadrada
		for (int i = 0; i < vetorNorma.length; i++){

			vetorNorma[i] = (float)Math.sqrt(vetorNorma[i]);

		}
	}

	//atualiza a hash trocando a frequencia pelo valor do peso para cada token
	public void atualizaHashAbs(float vetorNormaAbs[]){

		//obtem o conjunto de chaves da hash
		Set<String> chaves = hash.keySet();

		//percorre todas as chaves da hash
		for (String chaveAtual: chaves){

			//obtem o conjunto de registro de cada chave
			List<Registro> lista = hash.get(chaveAtual);

			//percorre todas os registros da chave
			for (Registro registro: lista){

				float valor = registro.getValorAbs();
				float maxFreq = Extracao.getVetorMaxFreqAbs().get(registro.getIndice());
				float freqNormalizada = valor/maxFreq;

				registro.setValorAbs(freqNormalizada);

				// Inicia o calculo da norma do documento fazendo o somatorio do quadrado do peso
				vetorNormaAbs[registro.getIndice()] = vetorNormaAbs[registro.getIndice()] + (freqNormalizada * freqNormalizada);
			}
		}

		// Atualiza vetor norma para raiz quadrada
		for (int i = 0; i < vetorNormaAbs.length; i++){

			vetorNormaAbs[i] = (float)Math.sqrt(vetorNormaAbs[i]);

		}
	}

	//Imprimi a hash que armazena o vocabulário e os respectivos valores
	public void printHash(){
		//obtem o conjunto de chaves da hash
		Set<String> tokens = hash.keySet();
		for (String token: tokens){

			//obtem os valores para cada token(chave)
			List<Registro> list = hash.get(token);
			System.out.println("Token: "+token);

			//percorre todas os registros(documento e valor) da chave
			for (Registro registro: list){

				System.out.println("\tArtigo: "+registro.getIndice()+ "\tFrequencia: "+ registro.getValor());
			}
		}
	}    
}